package com.lib.core.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.lib.core.view.LoadingDialog
import com.scwang.smart.refresh.layout.api.RefreshLayout
import java.lang.reflect.ParameterizedType

abstract class BaseFragment<VB : ViewBinding, VM : BaseViewModel> : Fragment() {



    protected lateinit var binding: VB
        private set

    protected lateinit var viewModel: VM
        private set

    private val loadingDialog: LoadingDialog by lazy { LoadingDialog(context) }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
        initData()
        registerUIChange()
        observeData()
    }

    open fun observeData() {

    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // ---- ViewBinding 反射 ----
        val type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments
        val vbClass = type[0] as Class<*>
        val vmClass = type[1] as Class<VM>

        val method = vbClass.getMethod(
            "inflate",
            LayoutInflater::class.java,
            ViewGroup::class.java,
            Boolean::class.java
        )
        @Suppress("UNCHECKED_CAST")
        binding = method.invoke(null, inflater, container, false) as VB

        // ---- ViewModel 自动创建 ----
        viewModel = ViewModelProvider(this)[vmClass]

        return binding.root
    }



    abstract fun initView()

    open fun initData(){}


    private fun showLoadingDialog() {
        loadingDialog.show()
    }

    private fun dismissLoadingDialog() {
        loadingDialog.dismiss()
    }


    private fun registerUIChange() {
        viewModel.uiModel.showDialog.observe(viewLifecycleOwner) {
            if (it) {
                showLoadingDialog()
            } else {
                dismissLoadingDialog()
            }
        }
        viewModel.uiModel.finishRefresh.observe(viewLifecycleOwner) {
            finishRefresh()
        }
        viewModel.uiModel.finishLoadMore.observe(viewLifecycleOwner) {
            finishLoadMore(it)
        }
    }

    open fun getRefreshLayout(): RefreshLayout? {
        return null
    }


    protected open fun finishRefresh() {
        getRefreshLayout()?.finishRefresh()
    }

    protected open fun finishLoadMore(haveData: Boolean) {
        if (haveData)
            getRefreshLayout()?.finishLoadMore()
        else
            getRefreshLayout()?.finishLoadMoreWithNoMoreData()
    }
}